package com.atguigu.gmall.product.service.impl;

import com.atguigu.cache.service.BitmapService;
import com.atguigu.cache.service.CacheService;
import com.atguigu.gmall.common.constant.RedisConstant;
import com.atguigu.gmall.feign.search.SearchFeignClient;
import com.atguigu.gmall.model.product.entity.*;
import com.atguigu.gmall.model.product.to.CategoryView;
import com.atguigu.gmall.model.product.vo.SkuInfoVO;
import com.atguigu.gmall.model.search.Goods;
import com.atguigu.gmall.model.search.SearchAttr;
import com.atguigu.gmall.product.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.product.mapper.SkuInfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author jiamin
 * @description 针对表【sku_info(库存单元表)】的数据库操作Service实现
 * @createDate 2023-08-14 20:41:58
 */
@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements SkuInfoService {

    @Autowired
    SkuImageService skuImageService;

    @Autowired
    SkuAttrValueService skuAttrValueService;

    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    BitmapService bitmapService;


    @Autowired
    ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    BaseCategory3Service baseCategory3Service;

    @Autowired
    BaseTrademarkService baseTrademarkService;

    @Autowired
    BaseAttrInfoService baseAttrInfoService;


    @Autowired
    SearchFeignClient searchFeignClient;

    @Autowired
    CacheService cacheService;


    @Transactional
    @Override
    public void saveSkuInfo(SkuInfoVO skuInfoVO) {
        //1. 先插入sku_info表
        SkuInfo skuInfo = new SkuInfo();
        BeanUtils.copyProperties(skuInfoVO, skuInfo);
        baseMapper.insert(skuInfo);

        Long skuId = skuInfo.getId();

        //2. 插入sku_img信息
        List<SkuImage> skuImageList = skuInfoVO.getSkuImageList().stream().map(item -> {
            SkuImage skuImage = new SkuImage();
            BeanUtils.copyProperties(item, skuImage);
            skuImage.setSkuId(skuId);
            return skuImage;
        }).collect(Collectors.toList());

        skuImageService.saveBatch(skuImageList);

        //3.插入sku_attr_value信息
        List<SkuAttrValue> skuAttrValueList = skuInfoVO.getSkuAttrValueList().stream().map(item -> {
            SkuAttrValue skuAttrValue = new SkuAttrValue();
            BeanUtils.copyProperties(item, skuAttrValue);
            skuAttrValue.setSkuId(skuId);
            return skuAttrValue;
        }).collect(Collectors.toList());
        skuAttrValueService.saveBatch(skuAttrValueList);

        //4.插入sku_sale_attr_value信息
        List<SkuSaleAttrValue> skuSaleAttrValueList = skuInfoVO.getSkuSaleAttrValueList().stream().map(item -> {
            SkuSaleAttrValue skuSaleAttrValue = new SkuSaleAttrValue();
            skuSaleAttrValue.setSkuId(skuId);
            skuSaleAttrValue.setSpuId(skuInfoVO.getSpuId());
            skuSaleAttrValue.setSaleAttrValueId(item.getSaleAttrValueId());
            return skuSaleAttrValue;
        }).collect(Collectors.toList());

        skuSaleAttrValueService.saveBatch(skuSaleAttrValueList);
    }

    @Override
    public void initBitmap() {
        lambdaQuery().select(SkuInfo::getId).list().stream().map(SkuInfo::getId).forEach(id -> {
            bitmapService.set(RedisConstant.REDIS_SKU_INFO_BITMAP, id, true);
        });
    }

    @Override
    public void onSale(Long skuId) {
        lambdaUpdate()
                .eq(SkuInfo::getId, skuId).set(SkuInfo::getIsSale, 1)
                .update();

        //加上位图
        bitmapService.set(RedisConstant.REDIS_SKU_INFO_BITMAP, skuId, true);

        //es加入商品信息
        Goods goods = prepareGoods(skuId);
        searchFeignClient.saveGoods(goods);


    }

    @Override
    public void cancelSale(Long skuId) {
        lambdaUpdate()
                .eq(SkuInfo::getId, skuId)
                .set(SkuInfo::getIsSale, 0)
                .update();
        //删除位图占位
        bitmapService.set(RedisConstant.REDIS_SKU_INFO_BITMAP, skuId, false);

        //调用延迟双删逻辑删除缓存中数据
        cacheService.delayDoubleDelete(RedisConstant.REDIS_SKU_INFO_KEY+skuId,10L, TimeUnit.MINUTES);

        //es中删除数据
        searchFeignClient.delGoods(skuId);
    }

    private Goods prepareGoods(Long skuId) {
        //创建商品对象
        Goods goods = new Goods();
        //查询skuInfo信息封装到Goods
        CompletableFuture<SkuInfo> skuInfoleFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfo skuInfo = getById(skuId);
            //封装goods基本信息
            goods.setId(skuInfo.getId());
            goods.setDefaultImg(skuInfo.getSkuDefaultImg());
            goods.setTitle(skuInfo.getSkuName());
            goods.setPrice(skuInfo.getPrice());
            goods.setCreateTime(new Date());
            return skuInfo;
        }, threadPoolExecutor);

        //在查询skuInfo之后查询，该商品的三级分类信息
        CompletableFuture<Void> categoryViewFuture = skuInfoleFuture.thenAcceptAsync(result -> {
            CategoryView categoryView = baseCategory3Service.getCategoryByC3Id(result.getCategory3Id());
            goods.setCategory1Id(categoryView.getCategory1Id());
            goods.setCategory1Name(categoryView.getCategory1Name());
            goods.setCategory2Id(categoryView.getCategory2Id());
            goods.setCategory2Name(categoryView.getCategory2Name());
            goods.setCategory3Id(categoryView.getCategory3Id());
            goods.setCategory3Name(categoryView.getCategory3Name());
        }, threadPoolExecutor);
        //在查询skuInfo之后查询，该商品的品牌信息
        CompletableFuture<Void> trademarkFuture = skuInfoleFuture.thenAcceptAsync(result -> {
            BaseTrademark trademark = baseTrademarkService.getById(result.getTmId());
            goods.setTmId(trademark.getId());
            goods.setTmName(trademark.getTmName());
            goods.setTmLogoUrl(trademark.getLogoUrl());
        }, threadPoolExecutor);
        //查询平台属性和属性值信息
        CompletableFuture<Void> attrsFuture = CompletableFuture.runAsync(() -> {
            List<SearchAttr> attrs = baseAttrInfoService.getAttrInfoAndValue(skuId);
            goods.setAttrs(attrs);
        }, threadPoolExecutor);
        //点击量默认为0
        goods.setHotScore(0L);
        //线程执行结束后在返回结果
        CompletableFuture.allOf(categoryViewFuture, trademarkFuture, attrsFuture).join();
        return goods;
    }
}




